/**
 * @author Tobias Boehm
 *
 * 28.03.2011
 */
package org.anddev.andengine.extension.tbsengine.resource;

import java.util.HashMap;

import org.anddev.andengine.extension.tbsengine.gameobject.Unit;


/**
 * This is an ability for {@link Unit}s to create resources for multiple {@link ResourceAccount}s.
 * 
 * @author Tobias Boehm
 *
 */
public abstract class ResourceProducerForMultiAccountsAbility extends ResourceProducerAbility {

	protected final HashMap<ResourceAccount, Integer> mResourceAccountsAndDistributionWeight;
	protected int mWeightSum;
	
	public ResourceProducerForMultiAccountsAbility(final AbsBaseResourceType pResourceType, final int pProductionAmount, final String pName, final String pDescription, final int pIconTileID){
		super(pResourceType, pProductionAmount, pName, pDescription, pIconTileID);

		this.mResourceAccountsAndDistributionWeight = new HashMap<ResourceAccount, Integer>();
	}
	
	public void addResourceAccount(final ResourceAccount pResourceAccount) throws WrongResourceTypeException{
		
		if(pResourceAccount.getResourceType() != this.mResourceType){
			
			throw new WrongResourceTypeException();
		}
		
		this.addResourceAccount(pResourceAccount, 1);
	}
	
	public void addResourceAccount(final ResourceAccount pResourceAccount,final Integer pDistributionWeight) throws WrongResourceTypeException{

		if(pResourceAccount.getResourceType() != this.mResourceType){
			
			throw new WrongResourceTypeException();
		}
		
		this.mResourceAccountsAndDistributionWeight.put(pResourceAccount, pDistributionWeight);
	}
	
	public void removeResourceAccount(final ResourceAccount pResourceAccount){
		
		if(this.mResourceAccountsAndDistributionWeight.containsKey(pResourceAccount)){
			
			final int weightLoss = this.mResourceAccountsAndDistributionWeight.remove(pResourceAccount);
			
			this.mWeightSum -= weightLoss;
		}		
	}
		
	@Override
	protected void spreadResources(){
		
		float amountPerWeight = (float)this.mProductionAmount / this.mWeightSum;
		
		int amountLeft = this.mProductionAmount;
		
		for(ResourceAccount currentAccount : this.mResourceAccountsAndDistributionWeight.keySet()){
			
			if(amountLeft > 0){
				
				int tmpAmount = Math.round(amountPerWeight * this.mResourceAccountsAndDistributionWeight.get(currentAccount));
				
				if(currentAccount.hasAmountMAX()){
					
					tmpAmount = Math.min((currentAccount.getAmountMAX() - currentAccount.getCreditLine()),tmpAmount);
				} 
				
				try {
					currentAccount.transact(tmpAmount);
					
					amountLeft -= tmpAmount;
					
				} catch (ResourceAccountLimitExceededException e) {}
			}
		}
	}
}
